package org.example;

import com.alibaba.ttl.TransmittableThreadLocal;
import com.alibaba.ttl.TtlRunnable;
import com.alibaba.ttl.threadpool.TtlExecutors;
import com.google.common.base.Throwables;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.concurrent.*;
import java.util.stream.IntStream;

/**
 * @author weigang
 * @create 2022-11-02 16:35
 */

@Slf4j
public class TTLcode {

    static void testInheritableThreadLocal1(){
        final InheritableThreadLocal<String> parent = new InheritableThreadLocal<>();
        parent.set("value-set-in-parent");

        ExecutorService executor = Executors.newFixedThreadPool(1);
        executor.submit(() -> System.out.println(Thread.currentThread().getName() + ": " + parent.get()));
        // 输出结果：pool-1-thread-1: value-set-in-parent
        // 线程间消息传递成功
    }


    static void testInheritableThreadLocal2(){
        ExecutorService executor = Executors.newFixedThreadPool(1);
        executor.submit(() -> {}); // 先进行工作线程创建

        final InheritableThreadLocal<String> parent = new InheritableThreadLocal<>();
        parent.set("value-set-in-parent");
        executor.submit(() -> System.out.println(Thread.currentThread().getName() + ": " + parent.get()));
        // 输出结果：pool-1-thread-1: null
        // 线程间消息传递失败
    }


    static void testTtlInheritableThreadLocal_TTL(){
        ExecutorService executor = Executors.newFixedThreadPool(1);
        executor.submit(() -> {}); // 先进行工作线程创建

        // 使用TTL
        final TransmittableThreadLocal<String> parent = new TransmittableThreadLocal<>();
        parent.set("value-set-in-parent");
        // 将Runnable通过TtlRunnable包装下
        executor.submit(TtlRunnable.get(() -> System.out.println(Thread.currentThread().getName() + ": " + parent.get())));
        // 输出结果：pool-1-thread-1: value-set-in-parent
    }

    public static void asyncThreadPool() {
        TransmittableThreadLocal<String> transmittableThreadLocal = new TransmittableThreadLocal<>();
        transmittableThreadLocal.set("i am a transmittable parent");
        ExecutorService executorService = TtlExecutors.getTtlExecutorService(
                new ThreadPoolExecutor(0, 1, 1L, TimeUnit.MINUTES,
                        new LinkedBlockingQueue<>(500),
                        new ThreadFactoryBuilder()
                                .setNameFormat("thread-pool-%d")
                                .setUncaughtExceptionHandler((thread, ex) -> {
                                    log.info("thread pool raised error, ex:{}", Throwables.getStackTraceAsString(ex));
                                })
                                .build(),
                        (r, executor) -> {
                            log.info("this thread discard, thread pool reject");
                        }));

        for (int i = 0; i < 10; i++) {
            executorService.submit(() -> System.out.println(Thread.currentThread().getName() + ": " + transmittableThreadLocal.get())); // 先进行工作线程创建
        }


    }

    static ThreadLocal<SimpleDateFormat> threadLocal = ThreadLocal.withInitial(()-> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    public static void demo1() {
        IntStream.range(0, 5).forEach(i -> {
            // 创建5个线程，分别从threadLocal取出SimpleDateFormat，然后格式化日期
            new Thread(() -> {
                try {
                    System.out.println(threadLocal.get().parse("2022-11-11 00:00:00"));
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
            }).start();
        });
    }

    public static void main(String[] args) {
//        testInheritableThreadLocal1();
//        testInheritableThreadLocal2();
//        testTtlInheritableThreadLocal_TTL();
//        asyncThreadPool();
        demo1();
    }

}
